#pragma once

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <memory>
const std::string http_sep = "\r\n";

const std::string index_page = "index.html"; // 首页
const std::string root_dir = "./root_dir";   // 根目录

class HttpRequest
{
private:
    bool GetLine(std::string &str, std::string *line)
    {
        auto pos = str.find(http_sep);
        if (pos == std::string::npos)
            return false;
        *line = str.substr(0, pos); // \r\n
        str.erase(0, pos + http_sep.size());
        return true;
    }
    void PraseRequestLine()
    {
        // stringstream对象通过<<重载，实现以空格形式分割
        std::stringstream ss(_request_line);
        ss >> _method >> _url >> _http_version;

        if (_url == "/")
        {
            _path += _url;
            _path += index_page;
        }
        else
        {
            _path += _url;
        }
    }
    void PraseSuffix()
    {
        auto pos = _path.find(".");
        if (pos == std::string::npos)
            _suffix = ".html";
        else
            _suffix = _path.substr(pos);
    }
    // 获取当前path对应文件内容
    std::string GetFileContentOption(const std::string &path) // 这里的爆红有bug 代码没问题
    {
        std::ifstream in(path, std::ios::binary);
        if (in.is_open() == false)
            return "";
        in.seekg(0, in.end);
        int file_size = in.tellg();
        in.seekg(0, in.beg);

        std::string content;
        content.resize(file_size);
        in.read((char *)content.c_str(), file_size);

        // std::vector<char> content(file_size);
        // in.read(content.data(), file_size);
        in.close();
        return content;
    }

public:
    HttpRequest() : _request_blank(http_sep), _path(root_dir)
    {
    }

    void Deserialize(std::string &request)
    {
        // 解析请求行
        std::string line;
        bool ret = GetLine(request, &line);
        if (ret == false)
            return;
        _request_line = line;

        while (true)
        {
            ret = GetLine(request, &line);
            if (ret && line.empty())
            {
                _request_content = request;
                break;
            }
            else if (ret && line.empty() == false)
            {
                _request_header.push_back(line);
            }
            else
            {
                break;
            }
        }
    }

    std::string Get404Content()
    {
        return GetFileContentOption("./root_dir/404.html"); // 进入到404文件
    }
    std::string GetFileContent()
    {
        return GetFileContentOption(_path); // 正常进入解析到的地址
    }

    void Prase()
    {
        PraseRequestLine();

        PraseSuffix();
    }

    const std::string Path() const
    {
        return _path;
    }
        const std::string URL() const
    {
        return _url;
    }

    const std::string Suffix() const
    {
        return _suffix;
    }
    ~HttpRequest()
    {
    }

private:
    // Method url http_version
    std::string _request_line; // 请求行
    std::string _method;
    std::string _url;
    std::string _http_version;

    std::vector<std::string> _request_header; // 请求头

    std::string _request_blank; // 空行

    std::string _request_content; // 请求参数、有效载荷

    std::string _path;   // 访问资源的位置
    std::string _suffix; // 访问资源的文件后缀类型
};

class HttpResponse
{
private:
public:
    HttpResponse() : _http_version("HTTP/1.0"), _status_code(200), _status_code_desc("OK"), _response_blank(http_sep) {}

    void Make()
    {
        // 添加状态行
        _status_line = _http_version + " " + std::to_string(_status_code) + " " + _status_code_desc + "\r\n";
    }
    std::string Serialize()
    {
        std::string response_mesg = _status_line;
        for (auto &header : _response_header)
        {
            response_mesg += header;
        }
        response_mesg += _response_blank;
        response_mesg += _response_content;
        return response_mesg;
    }

    void SetCode(int code)
    {
        _status_code = code;
    }
    void SetDesc(const std::string &status_code_desc)
    {
        _status_code_desc = status_code_desc;
    }
    void SetHeaders(const std::string &header)
    {
        _response_header.push_back(header);
    }
    void SetContent(const std::string &content)
    {
        _response_content = content;
    }

private:
    // http版本 状态码 状态码描述
    std::string _status_line; // 状态行
    std::string _http_version;
    int _status_code;
    std::string _status_code_desc;

    std::vector<std::string> _response_header; // 响应头
    std::string _response_blank;               // 空行
    std::string _response_content;             // 响应内容
};